/**
 * 对象工具类
 */
export class ObjectUtil {
  /**
   * 将对象全部属性值设置为null
   */
  static setAllPropertiesToNull(obj) {
    if (ObjectUtil.isNullOrUndefined(obj)){
      return obj
    }
    for (const key in obj) {
      if (obj.hasOwnProperty(key)) {
        obj[key] = null
      }
    }
    return obj
  }

  /**
   * 判断对象是否为NullOrUndefined
   * @param obj 待检查对象
   * @returns boolean
   */
  static isNotNullAndUndefined(obj: any): boolean {
    return !ObjectUtil.isNullOrUndefined(obj)
  }

  /**
   * 判断对象是否为NullOrUndefined
   * @param obj 待检查对象
   * @returns boolean
   */
  static isNullOrUndefined(obj: any): boolean {
    return obj === null || obj === undefined
  }

  /**
   * 判断对象是否为空
   * @param obj 待检查对象
   * @returns boolean
   */
  static isNotEmpty(obj: any): boolean {
    return ObjectUtil.isEmpty(obj)
  }

  /**
   * 判断对象是否为空
   * @param obj 待检查对象
   * @returns boolean
   */
  static isEmpty(obj: any): boolean {
    return obj === null || obj === undefined || Object.keys(obj).length === 0
  }

  /**
   * 深拷贝对象
   * @param obj 待拷贝对象
   * @returns 拷贝后的新对象
   */
  static deepClone<T>(obj: T): T {
    if (obj === null || typeof obj !== 'object') {
      return obj
    }

    if (Array.isArray(obj)) {
      return obj.map((item) => this.deepClone(item)) as unknown as T
    }

    const clonedObj = {} as T
    for (const key in obj) {
      if (Object.prototype.hasOwnProperty.call(obj, key)) {
        clonedObj[key] = this.deepClone(obj[key])
      }
    }
    return clonedObj
  }

  /**
   * 合并对象
   * @param target 目标对象
   * @param source 源对象
   * @returns 合并后的对象
   */
  static merge<T>(target: T, source: Partial<T>): T {
    const result = this.deepClone(target)
    if (this.isEmpty(source)) {
      return result
    }

    for (const key in source) {
      if (Object.prototype.hasOwnProperty.call(source, key)) {
        if (typeof source[key] === 'object' && source[key] !== null) {
          result[key] = this.merge(result[key], source[key])
        } else {
          result[key] = source[key]
        }
      }
    }
    return result
  }

  /**
   * 移除对象中的空值属性
   * @param obj 待处理对象
   * @returns 处理后的对象
   */
  static removeEmpty<T extends object>(obj: T): Partial<T> {
    const result = {} as Partial<T>
    for (const key in obj) {
      if (Object.prototype.hasOwnProperty.call(obj, key)) {
        const value = obj[key]
        if (value !== null && value !== undefined && value !== '') {
          result[key] = value
        }
      }
    }
    return result
  }
}
